﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Win32;
using System.IO;
using System.Text.Json.Nodes;
using System.Text.Json;
using System.Windows;
using XYAC.Framework.MonitorTireMaterialManual.DataExporter;
using XYAC.Framework.MonitorTireMaterialManual.Entities;
using XYAC.Framework.MonitorTireMaterialManual.Extensions;
using XYAC.Framework.MonitorTireMaterialManual.IServices;
using System.Text;
using XYAC.Framework.MonitorTireMaterialManual.Converters;
using System.ComponentModel;
using XYAC.Framework.MonitorTireMaterialManual.common;
using System.Windows.Media;

namespace XYAC.Framework.MonitorTireMaterialManual.ViewModels
{
    /// <summary>
    /// 胎侧离线扫描检查表（半钢）
    /// 
    /// </summary>
    public partial class SemiSteelSideInspectionViewModel : ViewModelBase
    {
        /// <summary>
        /// 临时数据交换目录。
        /// 保存用户选择的最近一次的数据目录。
        /// 重启软件会丢失此目录而采用固定的初始目录。
        /// </summary>
        static string tempDataSwapFolder = "";
        /// <summary>
        /// 主观判断 是 不是
        /// </summary>
        private List<Item> mindCheck;
        public List<Item> MindCheckList
        {
            get => mindCheck;
            set => SetProperty(ref mindCheck, value);
        }

        /// <summary>
        /// 班次清单
        /// </summary>
        private List<Item> shiftList;
        public List<Item> ShiftList
        {
            get => shiftList;
            set => SetProperty(ref shiftList, value);
        }
        /// <summary>
        /// 主观判断 合格 还是不合格
        /// </summary>
        private List<Item> mindPassList;
        public List<Item> MindPassList
        {
            get => mindPassList;
            set => SetProperty(ref mindPassList, value);
        }
        public static string TempDataSwapFolder
        {
            get => tempDataSwapFolder;
            set => tempDataSwapFolder = value;
        }

        //[ObservableProperty]
        //private YB_LOT_INSPECT_Local _curentInspect;
        public QualityDataUploadViewModel? UploadViewModel { get; set; }
        [ObservableProperty]
        private string _scanDatetime;

        public SemiSteelSideInspectionViewModel(IOptionsMonitor<AppConfig> options, ILogger<QualityDataHistoryViewModel> logger, IServiceProvider provider)
        {
            this.AppConfig = options;
            this.Logger = logger;
            this.provider = provider;
            UploadViewModel = provider.GetService<QualityDataUploadViewModel>();
            this.UserId = this.AppConfig.CurrentValue.UserId;
            this.CurrentShift = this.AppConfig.CurrentValue.CurrentShift;
            MindCheckList = new List<Item>();
            ScanDatetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            MindCheckList.Add(new Item("√", "True"));
            MindCheckList.Add(new Item("×", "False"));

            ShiftList = new List<Item>();
            ShiftList.Add(new Item("早班", "早"));
            ShiftList.Add(new Item("夜班", "夜"));

            MindPassList = new List<Item>();
            MindPassList.Add(new Item("合格", "True"));
            MindPassList.Add(new Item("不合格", "False"));
        }

        #region Attributes
        [ObservableProperty]
        private IReadOnlyCollection<string> _autocompleteStrings = new List<String>()
        {
            "✔",
            "❌"
        };

        [ObservableProperty]
        private SemiSteelSideInspectionReport _semiSteelSideInspectionReport;

        public IOptionsMonitor<AppConfig> AppConfig { get; }
        public ILogger<QualityDataHistoryViewModel> Logger { get; }
        public DataFile DataFile { get; private set; }
        public Action CloseWindow { get; internal set; }

        private IServiceProvider provider;
        #endregion

        bool maySave = false;
        /// <summary>
        /// 打开txt报表数据
        /// </summary>
        [RelayCommand]
        private async void OpenReportData1()
        {
            try
            {
                if (!isPrecheck())
                {
                    MessageBox.Show("请先执行本班次今日的班前检点！", "应用提示", MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }

                string tempDir = TempDataSwapFolder;
                if (string.IsNullOrEmpty(tempDir))
                    tempDir = this.AppConfig.CurrentValue.Folder2Path;

                // 创建并配置 OpenFileDialog 对象
                var openFileDialog = new OpenFileDialog()
                {
                    InitialDirectory = tempDir,
                    Title = "Open Text File",
                    Filter = "文本文件 (*.txt)|*.txt",
                    Multiselect = false,
                };
                List<string> errors = null;
                // 显示文件选择对话框
                if (openFileDialog.ShowDialog() == true)
                {
                    string fileName = openFileDialog.FileName;
                    FileInfo fileInfo = new FileInfo(fileName);
                    TempDataSwapFolder = fileInfo.DirectoryName;

                    this.AppConfig.CurrentValue.Folder2Path = TempDataSwapFolder;
                    SaveNewJsonConfig();
                    // 加载并解析数据文件
                    this.DataFile = DataFileParser.LoadFromFile(fileName);

                    if (DataFile.Validate(out errors))
                    {
                        maySave = true;
                        //验证成功,赋值给本地视图模型
                        this.SemiSteelSideInspectionReport = new()
                        {
                            PlanId = UploadViewModel.CurrentUserChoicePlan?.InspectModel.SERIAL_NUMBER,
                            Shift = UploadViewModel.CurrentUserChoicePlan?.InspectModel.SHIFT,
                            ScanedDatetime = this.ScanDatetime,
                            SerialNumber = UploadViewModel.CurrentUserChoicePlan?.InspectModel.SERIAL_NUMBER,
                            SpecNameInfact = UploadViewModel.CurrentUserChoicePlan?.InspectModel.PART_NUMBER,
                            PlanDate = UploadViewModel.CurrentUserChoicePlan.InspectModel.PLAN_DATE.Value,
                            Eqp = UploadViewModel.CurrentUserChoicePlan?.InspectModel.EQP,

                            SpecName = this.DataFile.TypeName,
                            TotalArea = DataFile.Area,//总面积
                            TotalLeftArea = DataFile.LeftArea,
                            TotalRightArea = DataFile.RightArea,
                            MeasureArea = DataFile.MeasureArea,
                            MeasureLeftArea = DataFile.MeasureLeftArea,
                            MeasureRightArea = DataFile.MeasureRightArea,
                            //AreaPercent = Math.Abs(Math.Round(((DataFile.MeasureArea - DataFile.Area) / DataFile.Area) * 100F, 2)),
                            //AreaPercent = Math.Abs(Math.Round(((DataFile.Area - DataFile.MeasureArea) / DataFile.Area) * 100F, 2)),
                            AreaPercent = _data9(),
                            TotalWidth_Stable = _data10() + _data11(),// DataFile.StableKeys.LastOrDefault().Coordinate,
                            TotalWidth_Scan = _data14() + _data15(), //DataFile.MeasureKeys.LastOrDefault().Coordinate,
                            TotalWidth_ScanLeft = _data14(),//Math.Abs(DataFile.XReference - DataFile.MeasureKeys.FirstOrDefault().Coordinate),
                            TotalWidth_ScanRight = _data15(),//Math.Abs(DataFile.XReference - DataFile.MeasureKeys.LastOrDefault().Coordinate),
                            TotalWidth_Symmetry = _data18(),// Math.Abs(DataFile.XReference - (DataFile.MeasureKeys.LastOrDefault().Coordinate - DataFile.XReference)),

                            EndThick = (float)DataFile.MeasureKeys[0].Value,
                            XReference = DataFile.XReference,

                            SideLeftWidth = DataFile.SideLeftWidth,
                            SideRightWidth = DataFile.SideRightWidth,
                            SideLeftWidthInfact = DataFile.SideLeftWidthInfact,
                            SideRightWidthInfact = DataFile.SideRightWidthInfact,
                            LeftRightSubstract = Math.Abs(DataFile.SideLeftWidthInfact - DataFile.SideRightWidthInfact),
                            DataFileJson = JsonSerializeHelper.SerializeObjectToJson(DataFile),
                            Data9 = _data9(),
                            Data10 = _data10(),//
                            Data11 = _data10(),//_data11(),//
                            Data14 = _data14(),
                            Data15 = _data15(),
                            Data18 = _data18(),
                            Data27 = _data27(),
                            Data35 = _data35(),
                            Data37 = _data37(),
                            Data20 = _data20(),
                            Data21 = _data21(),//
                            Data22 = _data21(),//_data22(),//
                            Data23 = _data23(),
                        };
                    }
                    else
                    {
                        //弹出exception
                        MessageBox.Show("文件验证失败:\n" + string.Join("\n", errors), "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                // 记录错误日志
                Logger?.LogError(ex.Message, ex);
                MessageBox.Show("打开文件时出现错误: " + ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        [RelayCommand]
        private async void OpenReportData()
        {
            try
            {
                if (!isPrecheck())
                {
                    MessageBox.Show("请先执行本班次今日的班前检点！", "应用提示", MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }

                string tempDir = TempDataSwapFolder;
                if (string.IsNullOrEmpty(tempDir))
                    tempDir = this.AppConfig.CurrentValue.Folder2Path;

                // 创建并配置 OpenFileDialog 对象
                var openFileDialog = new OpenFileDialog()
                {
                    InitialDirectory = tempDir,
                    Title = "Open Text File",
                    Filter = "文本文件 (*.txt)|*.txt",
                    Multiselect = false,
                };
                List<string> errors = null;
                // 显示文件选择对话框
                if (openFileDialog.ShowDialog() == true)
                {
                    string fileName = openFileDialog.FileName;
                    FileInfo fileInfo = new FileInfo(fileName);
                    TempDataSwapFolder = fileInfo.DirectoryName;

                    this.AppConfig.CurrentValue.Folder2Path = TempDataSwapFolder;
                    SaveNewJsonConfig();
                    // 加载并解析数据文件
                    this.DataFile = DataFileParser.LoadFromFile(fileName);

                    if (DataFile.Validate(out errors))
                    {
                        maySave = true;
                        //验证成功,赋值给本地视图模型
                        this.SemiSteelSideInspectionReport = new();
                        this.SemiSteelSideInspectionReport.PropertyChanged += SemiSteelSideInspectionReport_PropertyChanged;
                        this.SemiSteelSideInspectionReport.PlanId = UploadViewModel.CurrentUserChoicePlan?.InspectModel.SERIAL_NUMBER;
                        this.SemiSteelSideInspectionReport.Shift = UploadViewModel.CurrentUserChoicePlan?.InspectModel.SHIFT;
                        this.SemiSteelSideInspectionReport.ScanedDatetime = this.ScanDatetime;
                        this.SemiSteelSideInspectionReport.SerialNumber = UploadViewModel.CurrentUserChoicePlan?.InspectModel.SERIAL_NUMBER;
                        this.SemiSteelSideInspectionReport.SpecNameInfact = UploadViewModel.CurrentUserChoicePlan?.InspectModel.PART_NUMBER;
                        this.SemiSteelSideInspectionReport.PlanDate = UploadViewModel.CurrentUserChoicePlan.InspectModel.PLAN_DATE.Value;
                        this.SemiSteelSideInspectionReport.Eqp = UploadViewModel.CurrentUserChoicePlan?.InspectModel.EQP;

                        this.SemiSteelSideInspectionReport.SpecName = this.DataFile.TypeName;
                        this.SemiSteelSideInspectionReport.TotalArea = DataFile.Area;//总面积
                        this.SemiSteelSideInspectionReport.TotalLeftArea = DataFile.LeftArea;
                        this.SemiSteelSideInspectionReport.TotalRightArea = DataFile.RightArea;
                        this.SemiSteelSideInspectionReport.MeasureArea = DataFile.MeasureArea;
                        this.SemiSteelSideInspectionReport.MeasureLeftArea = DataFile.MeasureLeftArea;
                        this.SemiSteelSideInspectionReport.MeasureRightArea = DataFile.MeasureRightArea;
                        //AreaPercent = Math.Abs(Math.Round(((DataFile.MeasureArea - DataFile.Area) / DataFile.Area) * 100F, 2)),
                        //AreaPercent = Math.Abs(Math.Round(((DataFile.Area - DataFile.MeasureArea) / DataFile.Area) * 100F, 2)),
                        this.SemiSteelSideInspectionReport.AreaPercent = _data9();
                        this.SemiSteelSideInspectionReport.TotalWidth_Stable = _data10() + _data11();// DataFile.StableKeys.LastOrDefault().Coordinate,
                        this.SemiSteelSideInspectionReport.TotalWidth_Scan = _data14() + _data15(); //DataFile.MeasureKeys.LastOrDefault().Coordinate,
                        this.SemiSteelSideInspectionReport.TotalWidth_ScanLeft = _data14();//Math.Abs(DataFile.XReference - DataFile.MeasureKeys.FirstOrDefault().Coordinate),
                        this.SemiSteelSideInspectionReport.TotalWidth_ScanRight = _data15();//Math.Abs(DataFile.XReference - DataFile.MeasureKeys.LastOrDefault().Coordinate),
                        this.SemiSteelSideInspectionReport.TotalWidth_Symmetry = _data18();// Math.Abs(DataFile.XReference - (DataFile.MeasureKeys.LastOrDefault().Coordinate - DataFile.XReference)),

                        this.SemiSteelSideInspectionReport.EndThick = (float)DataFile.MeasureKeys[0].Value;
                        this.SemiSteelSideInspectionReport.XReference = DataFile.XReference;

                        this.SemiSteelSideInspectionReport.SideLeftWidth = DataFile.SideLeftWidth;
                        this.SemiSteelSideInspectionReport.SideRightWidth = DataFile.SideRightWidth;
                        this.SemiSteelSideInspectionReport.SideLeftWidthInfact = DataFile.SideLeftWidthInfact;
                        this.SemiSteelSideInspectionReport.SideRightWidthInfact = DataFile.SideRightWidthInfact;
                        this.SemiSteelSideInspectionReport.LeftRightSubstract = Math.Abs(DataFile.SideLeftWidthInfact - DataFile.SideRightWidthInfact);
                        this.SemiSteelSideInspectionReport.DataFileJson = JsonSerializeHelper.SerializeObjectToJson(DataFile);
                        this.SemiSteelSideInspectionReport.Data9 = _data9();
                        this.SemiSteelSideInspectionReport.Data10 = _data10();//
                        this.SemiSteelSideInspectionReport.Data11 = _data10();//_data11(),//
                        this.SemiSteelSideInspectionReport.Data14 = _data14();
                        this.SemiSteelSideInspectionReport.Data15 = _data15();
                        this.SemiSteelSideInspectionReport.Data18 = _data18();
                        this.SemiSteelSideInspectionReport.Data27 = _data27();
                        this.SemiSteelSideInspectionReport.Data35 = _data35();
                        this.SemiSteelSideInspectionReport.Data37 = _data37();
                        this.SemiSteelSideInspectionReport.Data20 = _data20();
                        this.SemiSteelSideInspectionReport.Data21 = _data21();//
                        this.SemiSteelSideInspectionReport.Data22 = _data21();//_data22(),//
                        this.SemiSteelSideInspectionReport.Data23 = _data23();

                    }
                    else
                    {
                        //弹出exception
                        MessageBox.Show("文件验证失败:\n" + string.Join("\n", errors), "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                // 记录错误日志
                Logger?.LogError(ex.Message, ex);
                MessageBox.Show("打开文件时出现错误: " + ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void SemiSteelSideInspectionReport_PropertyChanged(object? sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Data9")
            {
                OnPropertyChanged(nameof(Data9TextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "Data14")
            {
                OnPropertyChanged(nameof(Data14TextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "Data15")
            {
                OnPropertyChanged(nameof(Data15TextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "ManuData10F")
            {
                OnPropertyChanged(nameof(ManuData10FTextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "ManuData11F")
            {
                OnPropertyChanged(nameof(ManuData11FTextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "ManuData13F")
            {
                OnPropertyChanged(nameof(ManuData13FTextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "ManuData14F")
            {
                OnPropertyChanged(nameof(ManuData14FTextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "Data18")
            {
                OnPropertyChanged(nameof(Data18TextColor)); // 触发颜色更新
            }

            if (e.PropertyName == "Data27")
            {
                OnPropertyChanged(nameof(Data27TextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "Data35")
            {
                OnPropertyChanged(nameof(Data35TextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "Data20")
            {
                OnPropertyChanged(nameof(Data20TextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "Data21")
            {
                OnPropertyChanged(nameof(Data21TextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "Data22")
            {
                OnPropertyChanged(nameof(Data22TextColor)); // 触发颜色更新
            }
            if (e.PropertyName == "Data23")
            {
                OnPropertyChanged(nameof(Data23TextColor)); // 触发颜色更新
            }
        }

        /// <summary>
        /// 上传当前条码以及关联数据到远程数据库,同时记录到本地数据记录
        /// </summary>
        [RelayCommand]
        private void UploadCurrentData()
        {
            if (!maySave)
            {
                MessageBox.Show("请先选择扫描的文本文件进行解析", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }
            //此处需要处理逻辑
            //将报表数据转换成Process_step
            //更新本地HisData缓存库状态
            //插入本地报表数据库
            //更新InpectData中间表数据状态
            if (this.SemiSteelSideInspectionReport is null)
            {
                MessageBox.Show("请上传报表数据进行解析", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }
            if (string.IsNullOrEmpty(this.UserId) || this.UserId.Trim().Length > 8)
            {
                MessageBox.Show("检测员ID不合法", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }
            //此处用于同步到本地库
            //此处代码逻辑
            //插入本地库
            //更新中间表状态
            this.SemiSteelSideInspectionReport.UserId = this.UserId;
            this.SemiSteelSideInspectionReport.Shift = this.CurrentShift;
            //SemiSteelSideInspectionReport.Data18 = _data18();
            //SemiSteelSideInspectionReport.Data27 = _data27();
            //SemiSteelSideInspectionReport.Data35 = _data35();
            //SemiSteelSideInspectionReport.Data9 = _data9();

            /*
            this.SemiSteelSideInspectionReport.CompensationCoefficient = this.CompensationCoefficient;
            //胎侧厚度
            this.SemiSteelSideInspectionReport.SidewallThickness_Stable = this.SidewallThickness_Stable;
            this.SemiSteelSideInspectionReport.SidewallThickness_ScanLeft = this.SidewallThickness_ScanLeft;
            this.SemiSteelSideInspectionReport.SidewallThickness_ScanRight = this.SidewallThickness_ScanRight;
            this.SemiSteelSideInspectionReport.SidewallThickness_Symmetry = this.SidewallThickness_Symmetry;
            //RC胶厚度
            this.SemiSteelSideInspectionReport.RCRubberThickness_Stable = this.RCRubberThickness_Stable;
            this.SemiSteelSideInspectionReport.RCRubberThickness_ScanLeft = this.RCRubberThickness_ScanLeft;
            this.SemiSteelSideInspectionReport.RCRubberThickness_ScanRight = this.RCRubberThickness_ScanRight;
            this.SemiSteelSideInspectionReport.RCRubberThickness_Symmetry = this.RCRubberThickness_Symmetry;
            */

            //var msg = "确实要上报数据！";// GetFormattedPropertyComments(this.SemiSteelSideInspectionReport);
            var msg = PropertyNameConverter.GetFormattedPropertyComments_v2(this.SemiSteelSideInspectionReport);

            if (MessageBox.Show(msg, "上报数据", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                using (var scope = this.provider.CreateScope())
                {
                    var reportService = scope.ServiceProvider.GetService<ILocalReportService>();
                    var uploadViewModel = scope.ServiceProvider.GetService<QualityDataUploadViewModel>();
                    int ret = reportService.Add<SemiSteelSideInspectionReport>(this.SemiSteelSideInspectionReport, uploadViewModel.CurrentUserChoicePlan.InspectModel);

                    if (ret == 0)
                    {
                        MessageBox.Show("保存数据失败,请稍后重试");
                    }
                    else
                    {
                        //关闭窗体
                        this.CloseWindow?.Invoke();
                    }
                }
            }
        }

        /// <summary>
        /// 检查是否已做过班前检点。
        /// </summary>
        /// <returns>已做过，返回真</returns>
        public bool isPrecheck()
        {
            using var scope = this.provider.CreateScope();
            var reportService = scope.ServiceProvider.GetService<ILocalReportService>();
            var CurrentShift = AppConfig.CurrentValue.GetCurrentShift();
            var dt = AppConfig.CurrentValue.GetCurrentProcuceDate();
            return reportService.isCheck(CurrentShift, dt);
        }

        internal void UpdateUserId(string text)
        {
            try
            {
                if (!string.IsNullOrEmpty(text))
                {
                    this.AppConfig.CurrentValue.UserId = text.Trim();
                    SaveNewJsonConfig();
                }
            }
            catch (Exception ex)
            {
                Logger?.LogError("保存用户ID失败", ex);
            }
        }
        internal void UpdateCurrentShift(string text)
        {
            try
            {
                this.AppConfig.CurrentValue.CurrentShift = text;
                SaveNewJsonConfig();
            }
            catch (Exception ex)
            {
                Logger?.LogError("保存当前班次失败！", ex);
            }
        }

        private void SaveNewJsonConfig()
        {
            try
            {
                const string configPath = "./Configs/";
                const string configFileName = "AppConfig.json";
                const string tempFileName = "AppConfig_temp.json";

                string configFullPath = Path.Combine(configPath, configFileName);
                string tempFullPath = Path.Combine(configPath, tempFileName);

                // 复制原始配置文件到临时文件
                File.Copy(configFullPath, tempFullPath, overwrite: true);
                var currentValue = this.AppConfig.CurrentValue.Clone();
                // 修改临时文件
                JsonObject appSetting;
                using (FileStream fs = new FileStream(tempFullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
                {
                    appSetting = JsonNode.Parse(fs).AsObject();

                    // 将当前的 CurrentAppConfig 序列化为 JsonNode
                    JsonNode sourceJsonNode = JsonSerializer.SerializeToNode(currentValue);

                    // 替换 "AppConfig" 节点
                    appSetting["AppConfig"] = sourceJsonNode;

                    // 清空文件并重置位置
                    fs.SetLength(0);
                    fs.Position = 0;

                    var options = new JsonSerializerOptions
                    {
                        WriteIndented = true // 格式化输出
                    };
                    JsonSerializer.Serialize(fs, appSetting, options);
                }

                // 原子性地替换原始配置文件
                File.Replace(tempFullPath, configFullPath, null);
            }
            catch (Exception ex)
            {
                this.Logger.LogError("保存配置文件失败", ex);
            }
        }
        [ObservableProperty]
        private string _userId;

        [ObservableProperty]
        private double _xReference;
        [ObservableProperty]
        private float _endThick;

        [ObservableProperty]
        private float _compensationCoefficient;

        [ObservableProperty]
        private float _sidewallThickness_Stable;
        [ObservableProperty]
        private float _sidewallThickness_ScanLeft;
        [ObservableProperty]
        private float _sidewallThickness_ScanRight;
        [ObservableProperty]
        private float _sidewallThickness_Symmetry;
        [ObservableProperty]
        private float _rCRubberThickness_Stable;
        [ObservableProperty()]
        private float _rCRubberThickness_ScanLeft;
        [ObservableProperty]
        private float _rCRubberThickness_ScanRight;
        [ObservableProperty]
        private float _rCRubberThickness_Symmetry;

        /// <summary>
        /// 当前班次
        /// </summary>
        [ObservableProperty]
        private string _currentShift;
        /// <summary>
        /// 总面积比 %    实测值
        /// SemiSteelSideInspectionReport.AreaPercent
        /// (检测面积-设定面积)/设定面积%
        /// (总面积实测值-总面积标准值)/总面积标准值*100%
        /// </summary>
        private float _data9()
        {
            return (float)(Math.Round(((DataFile.MeasureArea - DataFile.Area) / DataFile.Area) * 100F, 2));
        }

        /// <summary>
        /// 胎侧宽度(mm)  左 标准
        /// SemiSteelSideInspectionReport.SideLeftWidth
        /// TXT文档，[Keys]（总行数/2）+1行的左边数字
        /// 
        /// 此前用上面的规则，现规则调整如下：
        /// 1、获取[XReference]的数值
        /// 2、在MeasureKeys下左边数字中找最接近[XReference] 的数值
        /// 21、22 及 10、11 均按此算法。
        /// </summary>
        private float _data10()
        {
            //var pos = (int)(DataFile.StableKeys.Count / 2);
            List<NewValue> list = new List<NewValue>();
            foreach (var val in DataFile.MeasureKeys)
            {
                NewValue nv = new NewValue
                {
                    MeasureKey = val,
                    NValue = Math.Abs(val.Coordinate - DataFile.XReference),
                    RowIndex = val.Index,
                };
                list.Add(nv);
            }
            var ss1 = list.Min(t => t.NValue);
            var ss = list.Where(t => t.NValue == ss1).FirstOrDefault();
            //return (float)ss.MeasureKey.Coordinate;
            var pos = ss.RowIndex-1;
            return (float)DataFile.StableKeys[pos].Coordinate;
        }

        /// <summary>
        /// 胎侧宽度(mm)  右 标准
        /// SemiSteelSideInspectionReport.SideRightWidth
        /// 
        /// TXT文档，[Keys]（总行数/2）+1行的左边数字
        /// </summary>
        private float _data11()
        {
            var pos = (int)(DataFile.StableKeys.Count / 2);
            return (float)DataFile.StableKeys[pos].Coordinate;
        }


        /// <summary>
        /// 胎侧宽度(mm)  左 实测
        /// SemiSteelSideInspectionReport.SideLeftWidthInfact
        /// TXT文档，[XReference]的数值
        /// </summary>
        private float _data14()
        {
            return (float)DataFile.XReference;
        }


        /// <summary>
        /// 胎侧宽度(mm)  右 实测
        /// SemiSteelSideInspectionReport.SideRightWidthInfact
        /// TXT文档，[MeasureKeys]最后一行左边数字-[XReference]
        /// </summary>
        private float _data15()
        {
            return (float)(DataFile.MeasureKeys.LastOrDefault().Coordinate - DataFile.XReference);
        }

        /// <summary>
        /// 胎侧左右宽度差(mm) 实测
        /// SemiSteelSideInspectionReport.LeftRightSubstract
        /// 
        /// ABS(左边宽度-右边宽度)
        /// data18=abs(data14-data15)
        /// </summary>
        private float _data18()
        {
            return Math.Abs(_data14() - _data15());
        }

        /// <summary>
        /// 胎侧左右厚度差(mm) 实测值：
        /// ABS(左边厚度-右边厚度)
        /// data27 = abs(ManuData10F-ManuData11F)
        /// </summary>
        private float _data27()
        {
            return Math.Abs(ManuData10F - ManuData11F);
        }
        /// <summary>
        /// RC左右厚度差(mm) 实测值:
        /// ABS（左边厚度-右边厚度）
        /// data35= abs(ManuData13F-ManuData14F)
        /// </summary>
        private float _data35()
        {
            return Math.Abs(ManuData13F - ManuData14F);
        }
        /// <summary>
        /// 边缘端点厚度(mm) 实测值
        /// SemiSteelSideInspectionReport.EndThick
        /// 
        /// MeasureKeys第1组第2位 (需确认)
        /// </summary>
        private float _data37()
        {
            return (float)DataFile.MeasureKeys[1].Value;
        }

        /// <summary>
        /// 边缘端点厚度(mm) 左
        /// TXT文档，[MeasureKeys]第一行右边数字,RECORD118
        /// </summary>
        private float? _data20()
        {
            return (float)DataFile.MeasureKeys[0].Value;
        }
        /// <summary>
        /// 边缘端点厚度(mm) 左
        /// TXT文档，[MeasureKeys]（总行数/2）+1行的右边数字,RECORD119
        /// </summary>
        private float? _data21()
        {
            //var pos = (DataFile.MeasureKeys.Count / 2);
            List<NewValue> list = new List<NewValue>();
            foreach (var val in DataFile.MeasureKeys)
            {
                NewValue nv = new NewValue
                {
                    MeasureKey = val,
                    NValue = Math.Abs(val.Coordinate - DataFile.XReference),
                    RowIndex = val.Index,
                };
                list.Add(nv);
            }
            var ss1 = list.Min(t => t.NValue);
            var ss = list.Where(t => t.NValue == ss1).FirstOrDefault();
            return (float)ss.MeasureKey.Value;
            //var pos = ss.RowIndex;
            //return (float)DataFile.MeasureKeys[pos].Value;
        }

        /// <summary>
        /// 边缘端点厚度(mm) 右
        /// TXT文档，[MeasureKeys]（总行数/2）+1行的右边数字,RECORD120
        /// </summary>
        private float? _data22()
        {
            var pos = (DataFile.MeasureKeys.Count / 2);
            return (float)DataFile.MeasureKeys[pos].Value;
        }
        /// <summary>
        /// 边缘端点厚度(mm) 右
        /// TXT文档，[MeasureKeys]最后一行右边数字，RECORD121
        /// </summary>
        private float? _data23()
        {
            return (float)DataFile.MeasureKeys.LastOrDefault().Value;
        }


        
        /// <summary>
        /// 其它点厚度(mm) 
        /// </summary>
        [ObservableProperty]
        private string _checkPoint38;
        /// <summary>
        /// 其它点厚度(mm)
        /// </summary>
        [ObservableProperty]
        private string _checkPoint39;


        [ObservableProperty]
        private float _manuData10D;
        [ObservableProperty]
        private float _manuData10F;
        [ObservableProperty]
        private float _manuData11D;
        [ObservableProperty]
        private float _manuData11F;

        [ObservableProperty]
        private float _manuData13D;
        [ObservableProperty]
        private float _manuData13F;
        [ObservableProperty]
        private float _manuData14D;
        [ObservableProperty]
        private float _manuData14F;

        /// <summary>
        /// RC上宽度(mm) 左 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData18D;
        /// <summary>
        /// RC上宽度(mm) 左 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData18E;
        /// <summary>
        /// RC上宽度(mm) 左 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData18F;

        /// <summary>
        /// RC上宽度(mm) 右 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData19D;
        /// <summary>
        /// RC上宽度(mm) 右 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData19E;
        /// <summary>
        /// RC上宽度(mm) 右 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData19F;

        /// <summary>
        /// RC下宽度(mm) 左 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData20D;
        /// <summary>
        /// RC下宽度(mm) 左 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData20E;
        /// <summary>
        /// RC下宽度(mm) 左 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData20F;

        /// <summary>
        /// RC下宽度(mm) 右 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData21D;
        /// <summary>
        /// RC下宽度(mm) 右 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData21E;
        /// <summary>
        /// RC下宽度(mm) 右 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData21F;

        /// <summary>
        /// RC左右宽度差(mm) 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData22D;
        /// <summary>
        /// RC左右宽度差(mm) 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData22E;
        /// <summary>
        /// RC左右宽度差(mm) 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData22F;


        /// <summary>
        /// 白胶宽度(mm) 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData23D;
        /// <summary>
        /// 白胶宽度(mm) 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData23E;
        /// <summary>
        /// 白胶宽度(mm) 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData23F;

        /// <summary>
        /// 白胶厚度(mm) 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData24D;
        /// <summary>
        /// 白胶厚度(mm) 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData24E;
        /// <summary>
        /// 白胶厚度(mm) 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData24F;

        /// <summary>
        /// 白胶底黑胶厚度(mm) 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData25D;
        /// <summary>
        /// 白胶底黑胶厚度(mm) 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData25E;
        /// <summary>
        /// 白胶底黑胶厚度(mm) 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData25F;


        /// <summary>
        /// 补强胶厚度(mm) 左 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData26D;
        /// <summary>
        /// 补强胶厚度(mm) 左 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData26E;
        /// <summary>
        /// 补强胶厚度(mm) 左 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData26F;

        /// <summary>
        /// 补强胶厚度(mm) 右 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData27D;
        /// <summary>
        /// 补强胶厚度(mm) 右 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData27E;
        /// <summary>
        /// 补强胶厚度(mm) 右 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData27F;

        /// <summary>
        /// 补强胶端点距离(mm)) 左 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData28D;
        /// <summary>
        /// 补强胶端点距离(mm)) 左 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData28E;
        /// <summary>
        /// 补强胶端点距离(mm)) 左 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData28F;

        /// <summary>
        /// 补强胶端点距离(mm)) 右 标准
        /// </summary>
        [ObservableProperty]
        private float _manuData29D;
        /// <summary>
        /// 补强胶端点距离(mm)) 右 公差
        /// </summary>
        [ObservableProperty]
        private float _manuData29E;
        /// <summary>
        /// 补强胶端点距离(mm)) 右 实际测量值
        /// </summary>
        [ObservableProperty]
        private float _manuData29F;

        /// <summary>
        /// 断面形状
        /// </summary>
        [ObservableProperty]
        private string _checkPoint40;

        /// <summary>
        /// 判定 41
        /// </summary>
        [ObservableProperty]
        private string _passStatus;

        /// <summary>
        /// 备注
        /// </summary>
        [ObservableProperty]
        private string _remark;
     
        /// <summary>
        /// Data9TextColor Data14TextColor Data15TextColor ManuData10FTextColor ManuData11FTextColor ManuData13FTextColor ManuData14FTextColor Data18TextColor
        /// </summary>
        public Brush Data9TextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;

                var hv = 5;
                var lv = -3;
                var rs = util.exeCheck(SemiSteelSideInspectionReport.Data9, hv, lv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }
        public Brush Data14TextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;

                var hv = SemiSteelSideInspectionReport.Data10 + 3;
                var lv = SemiSteelSideInspectionReport.Data10 - 3;
                var rs = util.exeCheck(SemiSteelSideInspectionReport.Data14, hv, lv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }
        public Brush Data15TextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;

                var hv = SemiSteelSideInspectionReport.Data11 + 3;
                var lv = SemiSteelSideInspectionReport.Data11 - 3;
                var rs = util.exeCheck(SemiSteelSideInspectionReport.Data15, hv, lv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }

        public Brush ManuData10FTextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;

                var hv = SemiSteelSideInspectionReport.ManuData10D + 0.3;
                var lv = SemiSteelSideInspectionReport.ManuData10D - 0.3;
                var rs = util.exeCheck(SemiSteelSideInspectionReport.ManuData10F, hv, lv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }
        public Brush ManuData11FTextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;

                var hv = SemiSteelSideInspectionReport.ManuData11D + 0.3;
                var lv = SemiSteelSideInspectionReport.ManuData11D - 0.3;
                var rs = util.exeCheck(SemiSteelSideInspectionReport.ManuData11F, hv, lv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }
        public Brush ManuData13FTextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;

                var hv = SemiSteelSideInspectionReport.ManuData13D + 0.3;
                var lv = SemiSteelSideInspectionReport.ManuData13D - 0.3;
                var rs = util.exeCheck(SemiSteelSideInspectionReport.ManuData13F, hv, lv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }
        public Brush ManuData14FTextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;

                var hv = SemiSteelSideInspectionReport.ManuData14D + 0.3;
                var lv = SemiSteelSideInspectionReport.ManuData14D - 0.3;
                var rs = util.exeCheck(SemiSteelSideInspectionReport.ManuData14F, hv, lv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }

        public Brush Data18TextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;
                var hv = 3;
                var rs = util.lessCheck(SemiSteelSideInspectionReport.Data18, hv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }
        /// <summary>
        /// Data27TextColor Data35TextColor Data20TextColor Data21TextColor Data22TextColor Data23TextColor
        /// </summary>
        public Brush Data27TextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;
                var hv = 0.3;
                var rs = util.lessCheck(SemiSteelSideInspectionReport.Data27, hv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }
        public Brush Data35TextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;
                var hv = 0.3;
                var rs = util.lessCheck(SemiSteelSideInspectionReport.Data35, hv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }
        public Brush Data20TextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;
                var hv = 0.8;
                var rs = util.lessCheck(SemiSteelSideInspectionReport.Data20, hv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }
        public Brush Data21TextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;
                var hv = 0.8;
                var rs = util.lessCheck(SemiSteelSideInspectionReport.Data21, hv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }
        public Brush Data22TextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;
                var hv = 0.8;
                var rs = util.lessCheck(SemiSteelSideInspectionReport.Data22, hv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }
        public Brush Data23TextColor
        {
            get
            {
                if (SemiSteelSideInspectionReport == null)
                    return Brushes.Black;
                var hv = 0.8;
                var rs = util.lessCheck(SemiSteelSideInspectionReport.Data23, hv);
                return rs ? Brushes.Black : Brushes.Red;
            }
        }

        // 当 RCRubberThickness_ScanLeft 发生变化时更新 RCRubberThickness_Symmetry
        partial void OnRCRubberThickness_ScanLeftChanged(float value)
        {
            // 手动计算并更新 RCRubberThickness_Symmetry
            RCRubberThickness_Symmetry = Math.Abs(RCRubberThickness_ScanLeft - RCRubberThickness_ScanRight);
        }

        // 当 RCRubberThickness_ScanRight 发生变化时更新 RCRubberThickness_Symmetry
        partial void OnRCRubberThickness_ScanRightChanged(float value)
        {
            // 手动计算并更新 RCRubberThickness_Symmetry
            RCRubberThickness_Symmetry = Math.Abs(RCRubberThickness_ScanLeft - RCRubberThickness_ScanRight);
        }


        Util util = new Util();
    }


    [DefaultProperty("NValue")]
    class NewValue
    {
        public double NValue { get; set; }
        public int RowIndex { get; set; }
        public MeasureKey MeasureKey { get; set; }
    }
}